<template>
  <div class="form-item" :class="classNames">
    <label class="form-item-label" v-if="label" :for="forId">
      <span class="form-item-required" v-if="showRequired">
        *
      </span>
      <span class="form-item-label-text">
        {{ label }}
        <el-tooltip v-if="needShowToast" :content="$t('common.form.preview.qualityInfoField.tips3')" placement="bottom" effect="light">
          <i class="iconfont icon-warning-circle-fill"></i>
        </el-tooltip>
        <template v-else-if="['taskEstimatedMileage','estimatedMileage','actualMileage'].includes(effectiveField.fieldName) && effectiveField.placeHolder.length > 0">
          <el-tooltip
            :content="effectiveField.placeHolder"
            placement="top"
          >
            <span class="iconfont icon-question-circle" style="font-size: 13px;"></span>
          </el-tooltip>
        </template>
        <div v-else-if="intelligentCheckField" class="form-item-intelligent-icon">
          <img :src="ilinkIcon" alt="" />
          <div></div>
        </div>
        <el-tooltip v-else-if="showPlacehoadler" :content="field.placeHolder" placement="top">
          <i class="iconfont icon-question-circle mar-l-4 font-13-i"></i>
        </el-tooltip>
      </span>
      
      <slot name="operation"></slot>

    </label>
    <div class="form-item-control form-item-project">
      <slot></slot>
      <div class="err-msg-wrap" v-if="needShowErrorDom">
        <div v-if="status" class="form-item-error">{{$t('common.validate.validating')}}</div>
        <div v-else-if="errMessage" class="form-item-error">{{errMessage}}</div>
      </div>
    </div>
  </div>
</template>

<script>
import Validator from "@src/util/validator";
import { findComponentUpward } from "@src/util/assist"
import _ from "lodash"
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum.ts'
import { isEmpty } from '@src/util/type'
import { getOssUrl } from '@src/util/assets'
const ilinkIcon = getOssUrl('/icon-ilink-mini.png')
import { needRowForOneEnum, getformItemClass } from 'src/component/form/util'

export default {
  name: "form-item",
  props: {
    label: String,
    validation: {
      type: [Boolean, Function],
      default: true
    }, // 是否开启验证
    /** 获取根元素（FormBuilder）的dom对象 */
    findRootEl: {
      type: Function,
      default() {
        let parent = findComponentUpward(this, ComponentNameEnum.FormBuilder)
        return parent && parent.$el;
      }
    },
    needValidate: {
      type: Boolean,
      default: true,
    },
    isNotNull: {
      type: Boolean,
      default: undefined
    },
    cardType:{
      type:String,
      default:''
    },
    // 用于额外表单项的校验
    propField: {
      type: Object
    },
    propValue: {
    },
    form: {
      default: () => {}
    },
    formCellCount:{
      type:Number,
      default:1
    },
    // 表单操作模式
    formEditingMode: {
      type: String,
      default: '', // create | edit
    },
  },
  data() {
    return {
      field: {},
      errMessage: "",
      valueFn: null, // function 用于获取注册字段的值
      status: false, // true 代表正在验证
      showErr: false,
      ilinkIcon
    }
  },
  watch: {
    propValue: {
      handler() {
        this.validateHandlerExtra()
      },
      deep: true // 避免层级过深的数据
    }
  },
  computed: {
    // 展示字段描述信息
    showPlacehoadler() {
      const fieldFormType = this.field?.formType || '';
      const parentFormType = this.field?.setting?.parentFormType || '';
      const isHelpTips = [ 'taskNo', 'customer', 'logistics', 'relationForm', 'quality', 'idcard', 'email'];
      if (isHelpTips.includes(fieldFormType) || parentFormType === 'idcard') {
        return false
      }
      return this.field?.placeHolderLanguage?.[this.$i18n.locale] || this.field?.placeHolder || false
    },
    // 展示连接器描述提示
    showConnectorTip() {
      return this.field.formType === 'connector' && this.field.placeHolder
    },
    // 展示国际货币描述提示
    showCurrencyTip() {
      return this.field.formType === 'currency' && this.field.placeHolder
    },
    // 控制展示不可更改提示
    needShowToast() {
      return this.field.needShowToast || false
    },
    effectiveField() { // 取field优先用这个
      return this.propField || this.field
    },
    classNames() {
      let class_ = getformItemClass(this.field, false, this.formCellCount)
      if(this.errMessage){
        class_ += ' err'
      }
      class_ += ` form-${this.field.formType}`
      return class_
    },
    /** 字段是否必填 */
    isRequired() {
      if(this.isNotNull !== undefined) return this.isNotNull;
      return this.effectiveField.isNull == 0;
    },
    showRequired() {
      return this.isRequired && !this.disabled;
    },
    forId(){
      if(!this.effectiveField.fieldName) return "";
      return `form_${this.effectiveField.fieldName}`;
    },
    formBuilderComponent() {
      return findComponentUpward(this, "form-builder")
    },
    /** 是否需要验证 */
    needValidation(){
      let validation = this.validation;
      return (typeof validation == "boolean" && validation) || typeof validation == "function"
    },
    disabled() {
      let field = this.effectiveField;
      return field.disabled
        || (field.setting && field.setting.defaultValueConfig && !!field.setting.defaultValueConfig.isNotModify && !!field.defaultValue);
    },
    isNullRelationFields() {
      return this.effectiveField.isNullRelationFields || []
    },
    // 是否开启智能质检
    intelligentCheckField() {
      // 新建不需要添加质检
      return false
      // const parent = findComponentUpward(this, ComponentNameEnum.FormBuilder)
      // if (!parent || this.field?.formType !== 'attachment') return false
      // return parent.$props.intelligentConfig && Object.keys(parent.$props.intelligentConfig).length > 0
    },
    isCellLast(){
      return this.field?.isCellLast !== false
    },
    needShowErrorDom(){
      return this.field?.formType !== 'separator'
    }
  },
  methods: {
    /** 
     * @description 默认返回true, 确保不影响表单提交 
     * @param {Boolean} isSample 是否是简单模式 (简单模式的概念是单个字段的单个验证)
    */
    validate(isSample = true) {
      if (typeof this.valueFn != "function" || !this.needValidate) return true;
      
      this.status = false;
      this.errMessage = "";
      
      let value = this.valueFn();
      let formBuilderComponent = this.formBuilderComponent || {}
      
      return Validator.validate(value, this.effectiveField, formBuilderComponent.value, formBuilderComponent.mode, this.changeStatus, isSample, formBuilderComponent,this.cardType)
        .then(res => {
          
          let validator = this.getValidator();
          
          // 多选一必填项校验
          if (this.isNullRelationFields.length && !res) {
            let isNullRelationFieldsRes = this.isNullRelationFields.find(field => {
              let value = this.form[field.fieldName]
              let hasValue = !!value
              if (value instanceof Array) {
                hasValue = !!value.length
              }
              return hasValue
            })
            const data = this.isNullRelationFields.map(v => v.displayName).join(this.$t('common.base.or'))
            if(!isNullRelationFieldsRes) res = this.$t('common.validate.oneIsRequired', {data})
          }
          return res == null && typeof validator == "function" 
            ? validator(value, this.effectiveField, this.changeStatus)
            : res;
        })
        .then(res => {
          return this.errMessage = res
        })
        .catch(err => {
          if(!err.message.startsWith("Request cancelled:")){
            console.error("validate err", err)
          }
        });
    },
    /** 远程验证时需要做延时 */
    delayValidate: _.debounce(function(){
      this.validate()
    }, 500),
    validateHandler(event) {
      this.isNullRelationFieldsNotice()
      event.stopPropagation(); // 阻止事件继续冒泡
      if(this.needValidation) {
        this.$nextTick(this.validate)
      }
    },
    isNullRelationFieldsNotice() {
      if (this.isNullRelationFields.length) {
        let data = this.isNullRelationFields.filter(field => 
          field.fieldName !== this.effectiveField.fieldName
        ).map(v => v.fieldName)
        let formBuilderComponent = this.formBuilderComponent || {}
        formBuilderComponent.updateRelation && formBuilderComponent.updateRelation(data)
        // this.$emit('updateRelation', data)
      }
    },
    // 额外表单项的校验
    validateHandlerExtra() {
      if(this.needValidation) {
        typeof this.validation === 'function' && this.$nextTick(() => {
          let res = this.validation()
          this.errMessage = typeof res === 'string' ? res : ''
        })
      }
    },
    /** 注册字段取值函数 */
    addFieldHandler(event) {
      
      if(!this.needValidation || !event.detail.field) {
        return event.stopPropagation()
      }
      
      if (isEmpty(event.detail.field)) {
        return event.stopPropagation()
      }
      
      this.valueFn = event.detail.value;
      this.field = event.detail.field;
      
      event.detail.validate = this.validate;
    },
    removeFieldHandler(event) {
      if(!this.needValidation) return event.stopPropagation();
      
      /** 此处因为dom 会被移出document, 所以事件不会冒泡至 FormBuilder组件中, 需要手动触发 */
      let rootEl = this.findRootEl()
      if(null != rootEl) {
        let params = event.detail;
        let e = new CustomEvent("form.remove.field", {detail: params, bubbles: true})
        rootEl.dispatchEvent(e);
      }
      this.valueFn = null;
    },
    changeStatus(value){
      this.status = !!value;
    },
    resetValidationStatus() {
      this.errMessage = "";
    },
    getValidator(){
      if(typeof this.validation == "function") return this.validation;
      return this.effectiveField.validator;
    }
  },
  mounted() {
    this.$el.addEventListener("form.add.field", this.addFieldHandler);
    this.$el.addEventListener("form.validate", this.validateHandler);
    this.$el.addEventListener("form.clear.validate", this.resetValidationStatus);
    this.$el.addEventListener("form.remove.field", this.removeFieldHandler);
  },
  destroyed() {
    this.$el.removeEventListener("form.validate", this.validateHandler)
    this.$el.removeEventListener("form.clear.validate", this.resetValidationStatus)
    this.$el.removeEventListener("form.add.field", this.addFieldHandler);
    this.$el.removeEventListener("form.remove.field", this.removeFieldHandler)
  }
}
</script>

<style lang="scss">
  .form-item.err :not(.is-success){
    input, textarea {
      border-color: #f56c6c !important;
    }

    .err-msg-wrap {
      color: #f56c6c !important;
    }
  }

  .form-item {
    font-size: 14px;
    /*margin-bottom: 10px;*/
    // padding-left: 12px;

    .form-item-label {
      // line-height: 1.4;
      margin-bottom: 8px;
      display: flex;
      align-items: center;
      white-space: nowrap;
      color: $text-color-primary;
      .icon-question-circle{
        color: #8c8c8c;
      }
      &-text {
        flex: 1;
        @include text-ellipsis;
      }
    }

    input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
      /* WebKit browsers */
      color: #B3B7C1;
    }
    input:-moz-placeholder, textarea:-moz-placeholder {
      /* Mozilla Firefox 4 to 18 */
      color: #B3B7C1;
    }
    input::-moz-placeholder, textarea::-moz-placeholder {
      /* Mozilla Firefox 19+ */
      color: #B3B7C1;
    }
    input:-ms-input-placeholder, textarea:-ms-input-placeholder {
      /* Internet Explorer 10+ */
      color: #B3B7C1;
    }
  }

  .form-item-required {
    color: red;
  }

  .form-item-control {
    flex: 1;

    .err-msg-wrap {
      min-height: 14px;
      padding-bottom: 3px;
    }
  }

  .form-item-error {
    font-size: 12px;
    line-height: 22px;
  }

  .form-item-attachment{
    .form-item-control{
      overflow: hidden;
    }
  }
  // 智能质检
  .form-item-label {
    position: relative;
    .form-item-intelligent-icon {
      position: absolute;
      top: -17px;
      img {
        width: 32px;
        height: auto;
      }
      div {
        position: absolute;
        top: 19px;
        left: 4px;
        width: 0px;
        height: 0px;
        margin: auto;
        border-top: 4px solid #ff5c0f;
        border-bottom: 4px solid #FFFFFF;
        border-left: 4px solid #FFFFFF;
        border-right: 4px solid #FFFFFF;
      }
    }
  }
  .form-connector {
    .form-item-label .form-item-connector-tip {
      color: #8c8c8c;
    }
  }
</style>
